import {
  downgradeComponent,
  downgradeInjectable,
} from "@angular/upgrade/static";
import { Ng2HeroesComponent } from "./components/ng2-heroes.component";
import { HeroesService } from "./services/hero";
import { TextFormatter } from "./utils/textFormatter";

// This Angular 1 module represents the AngularJS pieces of the application
export const ng1AppModule: ng.IModule = angular.module("ng1AppModule", []);

// #docregion ng1-hero
// This AngularJS component will be "upgraded" to be used in Angular
ng1AppModule.component("ng1Hero", {
  bindings: { hero: "<", onRemove: "&" },
  transclude: true,
  template: html`
    <div class="title" ng-transclude></div>
    <h2>{{ $ctrl.hero.name }}</h2>
    <p>{{ $ctrl.hero.description }}</p>
    <button class="btn btn-danger" ng-click="$ctrl.onRemove()">Remove</button>
  `,
});
// #enddocregion

// #docregion ng1-text-formatter-service
// This AngularJS service will be "upgraded" to be used in Angular
ng1AppModule.service("textFormatter", [TextFormatter]);
// #enddocregion

// #docregion downgrade-ng2-heroes-service
// Register an AngularJS service, whose value is the "downgraded" Angular injectable.
ng1AppModule.factory("heroesService", downgradeInjectable(HeroesService));
// #enddocregion

// #docregion ng2-heroes-wrapper
// This directive will act as the interface to the "downgraded" Angular component
ng1AppModule.directive(
  "ng2Heroes",
  downgradeComponent({ component: Ng2HeroesComponent }),
);
// #enddocregion

// #docregion example-app
// This is our top level application component
ng1AppModule.component("hybridApp", {
  // We inject the "downgraded" HeroesService into this AngularJS component
  // (We don't need the `HeroesService` type for AngularJS DI - it just helps with TypeScript
  // compilation)
  controller: [
    "heroesService",
    class componentController {
      heroesService: HeroesService;

      constructor(heroesService: HeroesService) {
        this.heroesService = heroesService;
      }
    },
  ],
  // This template makes use of the downgraded `ng2-heroes` component
  // Note that because its element is compiled by AngularJS we must use kebab-case attributes
  // for inputs and outputs
  template: html`
    <ng2-heroes
      [heroes]="$ctrl.heroesService.heroes"
      (add-hero)="$ctrl.heroesService.addHero()"
      (remove-hero)="$ctrl.heroesService.removeHero($event)"
    >
      <h1>Heroes</h1>
      <p class="extra">
        There are {{ $ctrl.heroesService.heroes.length }} heroes.
      </p>
    </ng2-heroes>
  `,
});
